package org.tokaf.rater;

import org.tokaf.TopKElement;
import org.tokaf.datasearcher.DataSearcher;
import org.tokaf.normalizer.SimpleNormalizer;

/**
 * <p>LevelRater gets the rating of inner rater and round it to the nearest
 * level.. These weight are stored in values field.</p> <p>Copyright (c) 2006</p>
 * @author Alan Eckhardt
 * @version 1.0
 */
public class LevelRater extends Rater {
	// double[][][] points;

	SimpleNormalizer norm = new SimpleNormalizer();

	TopKElement[] points;

	double[] rates;

	public LevelRater(String fields[], double[][] points, double[] rates) {
		this.points = new TopKElement[points.length];
		for (int i = 0; i < points.length; i++) {
			Double[] array = new Double[points[i].length];
			for (int j = 0; j < array.length; j++)
				array[j] = new Double(points[i][j]);
			TopKElement el = new TopKElement("" + i, array);
			this.points[i] = el;
		}
		this.fields = (String[]) fields.clone();
		// this.points = points;
		this.rates = rates;
	}

	public LevelRater(String fields[], TopKElement[] points, double[] rates) {
		this.fields = (String[]) fields.clone();
		this.points = points;
		this.rates = rates;
	}

	public double getRating(TopKElement el, DataSearcher[] data, double optional) {
		int level = -1;
		for (int i = 0; i < points.length; i++) {
			int k = 0;
			for (k = 0; k < el.getLength(); k++) {
				if (el.isNull(k)) {
					if (norm.Normalize(points[i], k) >= optional)
						break;
				} else if (norm.Normalize(points[i], k) >= data[k]
						.getNormalizer().Normalize(el, k))
					break;
			}
			if (k == el.getLength())
				level = i;
		}
		if (level == -1)
			return 0;
		return rates[level];
	}

	public double getRating(TopKElement el, DataSearcher[] data,
			TopKElement optional) {
		int level = -1;
		for (int i = 0; i < points.length; i++) {
			int k = 0;
			for (k = 0; k < el.getLength(); k++) {
				if (el.isNull(k)) {
					if (norm.Normalize(points[i], k) >= optional.getRating(k))
						break;
				} else if (norm.Normalize(points[i], k) >= el.getRating(k))
					break;
			}
			if (k == el.getLength())
				level = i;
		}

		if (level == -1)
			return 0;
		return rates[level];
	}

	public double getDerivation(int index, DataSearcher[] data, TopKElement el) {
		int level = -1;
		for (int i = 0; i < points.length; i++) {
			int k = 0;
			for (k = 0; k < el.getLength(); k++) {
				if (norm.Normalize(points[i], k) >= el.getRating(k))
					break;
			}
			if (k == el.getLength())
				level = i;
		}
		if (level == -1)
			return 0;
		return rates[level] - rates[level - 1];
	}

}
